home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / COMM / RPL60 / RPLMAT.INC < prev    next >
Text File  |  1992-12-31  |  5KB  |  143 lines

  1.  
  2.   {*}
  3.   {*source code copyright (c) 1985, by TurboPower Software*}
  4.   {*}
  5.   {*}
  6.  
  7.   function Match(var Lin : Line; Pat : PatPtr) : Boolean;
  8.     {-find a match anywhere in the line}
  9.   var
  10.     i, lPos, TagNum : Integer;
  11.     TagOn          : Boolean;
  12.  
  13.     function aMatch(var Lin : Line; OffSet : Integer; Pat : PatPtr) : Integer;
  14.       {-look for match of pattern list starting at pat with lin.val[offset...]}
  15.       {-return the last position that matched}
  16.     var
  17.       i, k           : Integer;
  18.       j              : PatPtr;
  19.       Done, Junk     : Boolean;
  20.       tTok           : Tokens;
  21.  
  22.       function oMatch(var Lin : Line; var i : Integer; Pat : PatPtr) : Boolean;
  23.         {-match one pattern element at pattern pointed to by pat, lin.val[i]}
  24.       var
  25.         Advance        : -1..255;
  26.         tTok           : Tokens;
  27.         k              : Integer;
  28.         c              : Char;
  29.       begin                       {omatch}
  30.         Advance := -1;
  31.         tTok := Pat^.Tok;
  32.           if IgnoreCase then c := UpCaseMac(Lin.Val[i]) else c := Lin.Val[i];
  33.         if c <> EndStr then begin
  34.           if tTok = tLitChar then begin
  35.             if c = Pat^.One then Advance := 1;
  36.           end else if tTok = tCcl then begin
  37.             k := Pos(c, Pat^.StrPtr^);
  38.             if k > 0 then Advance := 1;
  39.           end else if tTok = tnCcl then begin
  40.             if (c <> #13) and (c <> #10) then begin
  41.               k := Pos(c, Pat^.StrPtr^);
  42.               if k = 0 then Advance := 1;
  43.             end;
  44.           end else if tTok = tAny then begin
  45.             if (c <> #13) and (c <> #10) then Advance := 1;
  46.           end else if tTok = tBol then begin
  47.             if i = 1 then Advance := 0;
  48.           end else if tTok = tEol then begin
  49.             if (c = #13) and (Lin.Val[Succ(i)] = #10) then Advance := 0;
  50.           end else if tTok = tNil then begin
  51.             Advance := 0;
  52.           end else if tTok = tbTag then begin
  53.             Advance := 0;
  54.             if not(TagOn) then begin
  55.               TagNum := Succ(TagNum);
  56.               TagOn := True;
  57.             end;
  58.           end else if tTok = teTag then begin
  59.             Advance := 0;
  60.             TagOn := False;
  61.           end else if tTok = tGroup then begin
  62.             {we treat a group as a "character", but allow advance of multiple chars}
  63.             {recursive call to amatch}
  64.             k := aMatch(Lin, i, Pat^.NestPtr);
  65.             if k >= i then begin
  66.               i := k;
  67.               Advance := 0;
  68.             end;
  69.           end;
  70.         end else begin
  71.           {at end of line}
  72.           {end tag marks match}
  73.           if (tTok = teTag) then Advance := 0;
  74.         end;
  75.  
  76.         if Advance >= 0 then begin
  77.           {ignore tag words here, since they are not used}
  78.           oMatch := True;
  79.           i := i+Advance;
  80.         end else
  81.           oMatch := False;
  82.  
  83.       end;                        {omatch}
  84.  
  85.     begin                         {amatch}
  86.       Done := False;
  87.       j := Pat;
  88.       while not(Done) and (j <> nil) do begin
  89.         tTok := j^.Tok;
  90.         if tTok = tClosure then begin
  91.           {a closure}
  92.           j := j^.Next;           {step past the closure in the pattern list}
  93.           i := OffSet;            {leave the current line position unchanged}
  94.           {match as many as possible}
  95.           while not(Done) and (Lin.Val[i] <> EndStr) do begin
  96.             if not(oMatch(Lin, i, j)) then Done := True;
  97.           end;
  98.           {i points to the location that caused a non-match}
  99.           {match rest of pattern against rest of input}
  100.           {shrink closure by one after each failure}
  101.           Done := False;
  102.           while not(Done) and (i >= OffSet) do begin
  103.             {call amatch recursively}
  104.             k := aMatch(Lin, i, j^.Next);
  105.               if k > 0 then Done := True else i := Pred(i);
  106.           end;
  107.           OffSet := k;            {if k=0 then failure else success}
  108.           Done := True;
  109.         end else if tTok = tMaybeOne then begin
  110.           {a 0 or 1 closure}
  111.           j := j^.Next;           {step past the closure marker}
  112.           {match or no match is ok, but advance lin cursor if matched}
  113.           Junk := oMatch(Lin, OffSet, j);
  114.           {advance to the next pattern token}
  115.           j := j^.Next;
  116.         end else if not(oMatch(Lin, OffSet, j)) then begin
  117.           if j^.NexTok then begin
  118.             {we get another chance because of alternation}
  119.             j := j^.Next;
  120.           end else begin
  121.             {omatch failed, can't back up}
  122.             OffSet := 0;
  123.             Done := True;
  124.           end;
  125.         end else begin            {omatch succeeded}
  126.           {skip over alternates if we matched already}
  127.           while j^.NexTok and (j^.Next <> nil) do j := j^.Next;
  128.           {move to the next non-alternate}
  129.           j := j^.Next;
  130.         end;
  131.       end;
  132.       aMatch := OffSet;
  133.     end;                          {amatch}
  134.  
  135.   begin                           {match}
  136.     lPos := 0; i := 1; TagNum := 0; TagOn := False;
  137.     while (Lin.Val[i] <> EndStr) and (lPos = 0) do begin
  138.       lPos := aMatch(Lin, i, Pat);
  139.       Match := (lPos > 0);
  140.       i := Succ(i);
  141.     end;
  142.   end;                            {match}
  143.